﻿using Abp;
using Abp.Collections.Extensions;
using Abp.Extensions;
using Abp.UI;
using Mt.Site.Core.Organizations.UserCache;
using Mt.Site.Core.Organizations.UserCache.Models;
using Mt.Site.Core.WorkFlows.Enum;
using Mt.Site.Core.WorkFlows.Process;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Mt.Site.Core.WorkFlows.Diy.Actions.Impl
{
    /// <summary>
    /// 部门主管 或 副主管可以在任何时候发起转办 ，移交工作给部门成员办理
    /// </summary>
    public class TransferAction : ActionBase
    {
        public override string UniqueName => WorkFlowConst.OperationName.TransferActionName;

        public TransferAction()
        {
        }

        public override bool NeedUserListArg => true;

        public override async Task<GetUserSelectionDataOutput> GetUserListAsync(IWorkFlowManager manager, Guid? nodeId, List<long> unitId)
        {
            var userInfo = await manager.UserAndUnitFinder.GetCurrentUserInfoAsync();
            if (userInfo.IsResponsibleLeader())
            {
                var list = await manager.GetUserListAsync(null, null, null);
                var blacklist = await manager.GetToDoUserListAsync();

                list.Users = list.Users.Where(c => !blacklist.Contains(c.Id)).OrderByDescending(c => c.Order).ToList();
                list.ActionScheme = ActionScheme.Parallel;

                var schemelist = new List<NameValue>();
                foreach (ActionScheme item in System.Enum.GetValues(typeof(ActionScheme)))
                {
                    var temp = new NameValue
                    {
                        Name = EnumHelper.GetEnumDescription(item),
                        Value = item.RawValue().ToString()
                    };
                    schemelist.Add(temp);
                }
                list.ActionSchemeList = schemelist;

                return list;
            }
            else
            {
                var unitIdList = CheckUnitIdList(userInfo);

                var list = await manager.GetUserListAsync(null, unitIdList, null);

                var blacklist = await manager.GetToDoUserListAsync();

                foreach (var user in list.Users)
                {
                    var thisUserInfo = await manager.UserAndUnitFinder.GetUserInfoAsync(user.Id);
                    foreach (var unit in unitIdList)
                    {
                        var post1 = thisUserInfo.Posts.Where(c => c.OrganizationId == unit).FirstOrDefault();
                        if (post1 != null)
                        {
                            var post2 = userInfo.Posts.Where(c => c.OrganizationId == unit).FirstOrDefault();
                            if (post2 != null)
                            {
                                int a = post1.PostLevel.RawValue();
                                int b = post2.PostLevel.RawValue();
                                if (a > b)
                                {
                                    blacklist.Add(user.Id);
                                }
                                else if (a == b && !post2.DeputyPresiding)
                                {
                                    blacklist.Add(user.Id);
                                }
                            }
                        }
                    }
                }
                list.Users = list.Users.Where(c => !blacklist.Contains(c.Id)).OrderByDescending(c => c.Order).ToList();
                list.ActionScheme = ActionScheme.Parallel;

                var schemelist = new List<NameValue>();
                foreach (ActionScheme item in System.Enum.GetValues(typeof(ActionScheme)))
                {
                    var temp = new NameValue
                    {
                        Name = EnumHelper.GetEnumDescription(item),
                        Value = item.RawValue().ToString()
                    };
                    schemelist.Add(temp);
                }
                list.ActionSchemeList = schemelist;

                return list;
            }
        }


        public override async Task<bool> IsShowAsync(IWorkFlowManager manager)
        {
            var current = await manager.GetCurrentProcessAsync();
            if (current == null || current.OperationType == OperationType.PassRound)
            {
                return false;
            }

            if(!current.CheckIsCoOperator() && !current.CheckIsMainOperator())
            {
                if (current.ResponsibilityId == null || current.TrunkId == null)
                {
                    return false;
                }
            }

            var userInfo = await manager.UserAndUnitFinder.GetCurrentUserInfoAsync();
            if (userInfo.IsResponsibleLeader())
            {
                return true;
            }
            else
            {
                var actionState = await manager.CheckActionStateAsync();
                //var isBranchLine = await manager.IsBranchLine();
                var canOperate = manager.CanOperate(UniqueName); //节点定义里包含这个操作（要不拟稿，请假之类的操作也可以转办好像不太合适）

                if (actionState == ActionState.Todo && canOperate)
                {
                    // 用户可能在多个部门担任职务，无途径确认这个步骤里用户哪个职务在发挥作用
                    // 则 把几个部门的人员全拉取出来，让对方选择吧
                    var unitIdList = CheckUnitIdList(userInfo);
                    if (unitIdList.Count > 0)
                    {
                        return true;
                    }
                }
            }

            return false;
        }

        private List<long> CheckUnitIdList(UserInfoDto userInfo)
        {
            //主管的部门（部门主管）
            var result = new List<long>();

            foreach (var item in userInfo.Units)
            {
                if (userInfo.IsDepartmentHeadOrDeputyHead(item.Id))
                {
                    result.Add(item.Id);
                }
            }

           // 分管领导
           // foreach (var item in userInfo.Posts)
           // {
           //     if(item.PostLevel == PostGroup.ResponsibleLeader)
           //     {
           //         foreach (var postOrganizationId in item.PostOrganizations)
           //         {
           //             if(!result.Contains(postOrganizationId))
           //             {
           //                 result.Add(postOrganizationId);
           //             }
           //         }
           //     }
           //}
           return result;
        }

        public override async Task OperateAsync(IWorkFlowManager manager, object data)
        {
            var args = data as ActionArgs;
            if (args != null)
            {
                args.UserIdList = await manager.RemoveToDoStateUserBeforeAddTaskAsync(args.UserIdList);
            }
            if (args == null || args.UserIdList.IsNullOrEmpty())
            {
                throw new UserFriendlyException("请选择人员及步骤");
            }
            if (args.UserIdList.Count == 1)
            {
                args.ActionScheme = ActionScheme.Single;
            }

            var isShow = await IsShowAsync(manager);
            if (isShow)
            {
                var current = await manager.GetCurrentProcessAsync();

                var names = await manager.UserAndUnitFinder.GetUserNameListAsync(args.UserIdList);
                var fromName = await manager.UserAndUnitFinder.GetUserNameAsync(current.UserId);
                var nextNameStr = string.Join("、", names);
                string msg = $"转{nextNameStr}办理";

                await manager.HasSolved(args.ReplyMsg, msg, MoveMode.NewBranch);
                //写入新任务
                await manager.AddNewTaskInBranchAsync(current, args.UserIdList, args.ActionScheme, current.Id);
                //写入记录
                var scheme = $"({EnumHelper.GetEnumDescription(args.ActionScheme)})";
                await manager.AddLogAsync(msg + scheme, fromName, nextNameStr, current?.Id);
            }
        }
    }
}